Skip to content

branch-4.1: [Fix](arrow flight) Fix arrow::Status inline static empty msg core (#63191)#63267

Merged
yiguolei merged 1 commit into
apache:branch-4.1from
linrrzqqq:pick-63191-branch-4.1
May 20, 2026
Merged

branch-4.1: [Fix](arrow flight) Fix arrow::Status inline static empty msg core (#63191)#63267
yiguolei merged 1 commit into
apache:branch-4.1from
linrrzqqq:pick-63191-branch-4.1

Conversation

@linrrzqqq
Copy link
Copy Markdown
Collaborator

pick: #63191

…pache#63191)

Related PR: apache#62489

Problem Summary:

```cpp
static const std::string no_message = "";
return ok() ? no_message : state_->msg;
```
In the clang-built Doris BE binary, this inline static `std::string` is
emitted as a weak/COMDAT object and placed in `.data.rel.ro`.
```bash
$ readelf -sW "$BIN" | c++filt | grep 'Status::message.*no_message'
105229: 000000007d6958e0    32 OBJECT  WEAK   DEFAULT   28 arrow::Status::message[abi:cxx11]() const::no_message[abi:cxx11]

$ readelf -SW doris/output/be/lib/doris_be | grep '\[ *28\]'
[28] .data.rel.ro      PROGBITS        000000007d0f7720 7d0f6720 7e4208 00  WA  0   0 32
```
After relocation, RELRO makes this section read-only. However, C++
function-local statics are lazily initialized on first execution, so the
first call to `Status::message()` tries to construct `no_message` at
runtime. The `std::string` constructor writes to the object storage in
`.data.rel.ro`, which triggers `SIGSEGV invalid permissions for mapped
object` like:

*FromStatus(arrow::Status)*
```text
*** Query id: 0-0 ***
*** is nereids: 0 ***
*** tablet id: 0 ***
*** Aborted at 1778559900 (unix time) try "date -d @1778559900" if you are using GNU date ***
*** Current BE git commitID: f02e9e680c8 ***
*** SIGSEGV invalid permissions for mapped object (@0xaaaaf1ecbf28) received by PID 3634450 (TID 3636517 OR 0xfffa35fe97c0) from PID 18446744073473408808; stack trace: ***
 0# doris::signal::(anonymous namespace)::FailureSignalHandler(int, siginfo_t*, void*) at /root/selectdb-core/be/src/common/signal_handler.h:421
 1# PosixSignals::chained_handler(int, siginfo_t*, void*) [clone .part.0] in /opt/jdk/lib/server/libjvm.so
 2# JVM_handle_linux_signal in /opt/jdk/lib/server/libjvm.so
 3# 0x0000FFFFAE091830 in linux-vdso.so.1
 4# std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> >(char const*, std::allocator<char> const&) at /root/toolchain/ldb-toolchain-v0.21/bin/../lib/gcc/aarch64-linux-gnu/13/../../../../include/c++/13/bits/basic_string.h:632
 5# arrow::flight::internal::TransportStatus::FromStatus(arrow::Status const&) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
 6# arrow::flight::transport::grpc::ToGrpcStatus(arrow::Status const&, grpc::ServerContext*) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
 7# arrow::flight::transport::grpc::(anonymous namespace)::GrpcServiceHandler::DoGet(grpc::ServerContext*, arrow::flight::protocol::Ticket const*, grpc::ServerWriter<arrow::flight::protocol::FlightData>*) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
 8# grpc::Status grpc::internal::CatchingFunctionHandler<grpc::internal::ServerStreamingHandler<arrow::flight::protocol::FlightService::Service, arrow::flight::protocol::Ticket, arrow::flight::protocol::FlightData>::RunHandler(grpc::internal::MethodHandler::HandlerParameter const&)::{lambda()apache#1}>(grpc::internal::ServerStreamingHandler<arrow::flight::protocol::FlightService::Service, arrow::flight::protocol::Ticket, arrow::flight::protocol::FlightData>::RunHandler(grpc::internal::MethodHandler::HandlerParameter const&)::{lambda()apache#1}&&) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
 9# grpc::internal::ServerStreamingHandler<arrow::flight::protocol::FlightService::Service, arrow::flight::protocol::Ticket, arrow::flight::protocol::FlightData>::RunHandler(grpc::internal::MethodHandler::HandlerParameter const&) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
10# grpc::Server::SyncRequest::ContinueRunAfterInterception() in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
11# grpc::Server::SyncRequest::Run(std::shared_ptr<grpc::Server::GlobalCallbacks> const&, bool) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
12# grpc::ThreadManager::MainWorkLoop() in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
13# grpc::ThreadManager::WorkerThread::WorkerThread(grpc::ThreadManager*)::$_0::__invoke(void*) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
14# grpc_core::(anonymous namespace)::ThreadInternalsPosix::ThreadInternalsPosix(char const*, void (*)(void*), void*, bool*, grpc_core::Thread::Options const&)::{lambda(void*)apache#1}::__invoke(void*) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
15# start_thread in /lib64/libc.so.6
16# thread_start in /lib64/libc.so.6
```

*ToStatus()*
```text
*** SIGSEGV invalid permissions for mapped object (@0x56448ff1ef38) received by PID 66637 (TID 67372 OR 0x7f2687017640) from PID 18446744071829581624; stack trace: ***
 0# doris::signal::(anonymous namespace)::FailureSignalHandler(int, siginfo_t*, void*) at ../src/common/signal_handler.h:417
 1# PosixSignals::chained_handler(int, siginfo*, void*) [clone .part.0] in /usr/lib/jvm/java-17-openjdk-amd64/lib/server/libjvm.so
 2# JVM_handle_linux_signal in /usr/lib/jvm/java-17-openjdk-amd64/lib/server/libjvm.so
 3# 0x00007F2836CE7520 in /lib/x86_64-linux-gnu/libc.so.6
 4# std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> >(char const*, std::allocator<char> const&) at /usr/local/ldb-toolchain-v0.26/bin/../lib/gcc/x86_64-pc-linux-gnu/15/include/g++-v15/bits/basic_string.h:707
 5# arrow::Status::WithDetail(std::shared_ptr<arrow::StatusDetail>) const in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
 6# arrow::flight::internal::TransportStatus::ToStatus() const in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
 7# arrow::flight::transport::grpc::FromGrpcStatus(grpc::Status const&, grpc::ClientContext*) in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
 8# arrow::flight::transport::grpc::(anonymous namespace)::GrpcClientInterceptorAdapter::Intercept(grpc::experimental::InterceptorBatchMethods*) in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
 9# grpc::internal::InterceptorBatchMethodsImpl::RunInterceptors() in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
10# grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata, grpc::internal::CallOpClientRecvStatus, grpc::internal::CallNoOp<3>, grpc::internal::CallNoOp<4>, grpc::internal::CallNoOp<5>, grpc::internal::CallNoOp<6> >::FinalizeResult(void**, bool*) in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
11# grpc::ClientReaderWriter<arrow::flight::protocol::FlightData, arrow::flight::protocol::FlightData>::Finish() in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
12# arrow::flight::transport::grpc::(anonymous namespace)::FinishableDataStream<grpc::ClientReaderWriter<arrow::flight::protocol::FlightData, arrow::flight::protocol::FlightData>, arrow::flight::internal::FlightData>::DoFinish() in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
13# arrow::flight::transport::grpc::(anonymous namespace)::WritableDataStream<grpc::ClientReaderWriter<arrow::flight::protocol::FlightData, arrow::flight::protocol::FlightData>, arrow::flight::internal::FlightData>::DoFinish() in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
14# arrow::flight::internal::ClientDataStream::Finish(arrow::Status) in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
15# arrow::flight::ClientStreamReader::Next() in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
16# doris::PythonClient::read_batch(std::shared_ptr<arrow::RecordBatch>*) at ./be/build_RELEASE/../src/udf/python/python_client.cpp:136
17# doris::PythonUDFClient::evaluate(arrow::RecordBatch const&, std::shared_ptr<arrow::RecordBatch>*) at ./be/build_RELEASE/../src/udf/python/python_udf_client.cpp:36
```

Move the empty message/detail sentinels out of the header inline path
and make non-OK statuses return `state_->msg` directly. This avoids
touching the empty OK-message sentinel on error paths and prevents the
inline weak/COMDAT `std::string` object from being lazily constructed
from a read-only mapping.
@linrrzqqq linrrzqqq requested a review from yiguolei as a code owner May 14, 2026 17:18
@hello-stephen
Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@linrrzqqq linrrzqqq changed the title [Fix](arrow flight) Fix arrow::Status inline static empty msg core (#63191) branch-4.1[Fix](arrow flight) Fix arrow::Status inline static empty msg core (#63191) May 14, 2026
@linrrzqqq linrrzqqq changed the title branch-4.1[Fix](arrow flight) Fix arrow::Status inline static empty msg core (#63191) branch-4.1: [Fix](arrow flight) Fix arrow::Status inline static empty msg core (#63191) May 14, 2026
@linrrzqqq
Copy link
Copy Markdown
Collaborator Author

run buildall

@yiguolei yiguolei merged commit 089dfab into apache:branch-4.1 May 20, 2026
29 of 33 checks passed
@linrrzqqq linrrzqqq deleted the pick-63191-branch-4.1 branch May 20, 2026 12:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants